package co.com.umobile.gui;

import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import co.com.umobile.R;
import co.com.umobile.application.GlobalState;
import co.com.umobile.persistence.ProviderUtilities;

public class LoginActivity extends AccountAuthenticatorActivity {
	
    private static final int DIALOG_TEXT_ENTRY = 1;
	
	/** Parameter confirm credentials. */
	public static final String PARAM_CONFIRMCREDENTIALS = "confirmCredentials";

	/** Parameter password. */
	public static final String PARAM_PASSWORD = "password";

	/** Parameter user name. */
	public static final String PARAM_USERNAME = "username";

	/** Parameter authenticated type. */
	public static final String PARAM_AUTHTOKEN_TYPE = "authtokenType";


	/** globalState is used to transfer data to other activity. */
	private GlobalState globalState;

	/** the userName. */
	private EditText userName;

	/** the user password. */
	private EditText password;

	/** the loginButton. */
	private Button loginButton;

	/** the worker thread. */
	private CustomAsyncTask asynch;

	/** the progress dialog. */
	private ProgressDialog progress;
	
	/** Was the original caller asking for an entirely new account. */
	protected boolean mRequestNewAccount = false;
	
	/**
	 * mobile user name.
	 */
	private String mUsername;

	/**
	 * mobile token.
	 */
	private String mAuthtoken;

	/**
	 * mobile token type.
	 */
	private String mAuthtokenType;

	/**
	 * mobile confirm credential.
	 */
	private Boolean mConfirmCredentials = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		getWindow().requestFeature(Window.FEATURE_ACTION_BAR);

		ActionBar actionBar = getActionBar();
		actionBar.setTitle(R.string.login_title);

		setContentView(R.layout.login_layout);

		globalState = (GlobalState) getApplication();

		try {
			int versionCode = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionCode;
			String versionName = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;

			globalState.setVersionCode(versionCode);
			globalState.setVersionName(versionName);

		} catch (NameNotFoundException e) {
			globalState.setVersionCode(null);
			globalState.setVersionName(null);
		}

		userName = (EditText) findViewById(R.id.editTextUserName);
		password = (EditText) findViewById(R.id.editTextPassword);
		loginButton = (Button) findViewById(R.id.buttonLogin);
		
		final Intent intent = getIntent();

		mUsername = intent.getStringExtra(PARAM_USERNAME);
		mAuthtokenType = intent.getStringExtra(PARAM_AUTHTOKEN_TYPE);
		mRequestNewAccount = mUsername == null;
		mConfirmCredentials = intent.getBooleanExtra(PARAM_CONFIRMCREDENTIALS, false);

		userName.setOnEditorActionListener(new OnEditorActionListener() {

			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				password.requestFocus();
				return true;
			}
		});

		password.setOnEditorActionListener(new OnEditorActionListener() {

			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				loginButton.performClick();
				return true;
			}
		});

		loginButton.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {

				asynch = new CustomAsyncTask();
				asynch.execute("");

			}
		});

		userName.setText("sgranada");
		password.setText("q1q1q1");
		
		progress = new ProgressDialog(this);
		progress.setIndeterminate(true);
		progress.setMessage(getApplicationContext().getResources().getString(R.string.login_loading));
		progress.setCancelable(false);
 
		progress.setButton(getApplicationContext().getResources().getString(R.string.cancel),
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						globalState.setLoginDisable(true);
					}
				});
		
		if(globalState.getPort() == null || globalState.getHost() == null){
			showDialog(DIALOG_TEXT_ENTRY);
		}
		

	}

	/**
	 * Class that syncronize the user information.
	 * 
	 * @author sergiogranada
	 * 
	 */
	class CustomAsyncTask extends AsyncTask<String, Void, Void> {

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPreExecute()
		 */
		@Override
		protected void onPreExecute() {
			InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			imm.hideSoftInputFromWindow(password.getApplicationWindowToken(), 0);
			imm.hideSoftInputFromWindow(userName.getApplicationWindowToken(), 0);

			progress.show();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		@Override
		protected Void doInBackground(String... params) {
			globalState.setLoginDisable(false);
			String userNameText = userName.getText().toString();
			String passwordText = password.getText().toString();
			globalState.getLoginServices().authenticateuser(LoginActivity.this, userNameText, passwordText);
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		@Override
		protected void onPostExecute(Void result) {
			globalState.setLoginDisable(false);

			if (progress != null && progress.isShowing()) {
				progress.dismiss();
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onCancelled()
		 */
		@Override
		protected void onCancelled() {
			globalState.setLoginDisable(true);
			clearPasswordField();
		}

	};

	/**
	 * clears the password field.
	 */
	public void clearPasswordField() {
		password.setText("");
		password.requestFocus();
	}
	
	/**
	 * Called when the authentication process completes (see attemptLogin()).
	 */
	public void onAuthenticationResult() {
		if (!mConfirmCredentials) {
			finishLogin();
		} else {
			finishConfirmCredentials(true);
		}
	}

	
	/**
	 * finishes the login process and sets the sync adapters properties.
	 */
	protected void finishLogin() {

		mUsername = globalState.getUserSession().getUserCode();

		final Account account = new Account(mUsername, ProviderUtilities.ACCOUNT_TYPE);

		if (mRequestNewAccount) {

			ProviderUtilities.setSyncPropertiesByProvider(account, ProviderUtilities.SUBJECT_AUTORITY, false);
			ProviderUtilities.setSyncPropertiesByProvider(account, ProviderUtilities.PLACE_AUTORITY, false);

			AccountManager.get(this).addAccountExplicitly(account, password.getText().toString(), null);

			ContentResolver.setMasterSyncAutomatically(false);

		} else {
			AccountManager.get(this).setPassword(account, password.getText().toString());
		}
		final Intent intent = new Intent();
		mAuthtoken = password.getText().toString();
		intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mUsername);
		intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, ProviderUtilities.ACCOUNT_TYPE);
		if (mAuthtokenType != null && mAuthtokenType.equals(ProviderUtilities.AUTHTOKEN_TYPE)) {
			intent.putExtra(AccountManager.KEY_AUTHTOKEN, mAuthtoken);
		}
		setAccountAuthenticatorResult(intent.getExtras());
		setResult(RESULT_OK, intent);
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
        case DIALOG_TEXT_ENTRY:
            // This example shows how to add a custom layout to an AlertDialog
            LayoutInflater factory = LayoutInflater.from(this);
            final View textEntryView = factory.inflate(R.layout.ip_dialog_text_entry, null);
            return new AlertDialog.Builder(LoginActivity.this)
                .setIconAttribute(android.R.attr.alertDialogIcon)
                .setTitle(R.string.ip_dialog_title)
                .setView(textEntryView)
                .setPositiveButton(R.string.ip_dialog_ok, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                    	EditText ipEditText = (EditText) textEntryView.findViewById(R.id.ip_edit);
                    	EditText portEditText = (EditText) textEntryView.findViewById(R.id.port_edit);
                    	
                    	globalState.setIpAddress(ipEditText.getText().toString());
                    	globalState.setIpPort(portEditText.getText().toString());
                    	
                    	dialog.cancel();
                    }
                })
                .setNegativeButton(R.string.ip_dialog_cancel, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                    	dialog.cancel();
                    }
                })
                .create();
		}
		
    return null;
	}
	
	/**
	 * Method that confirm credentials of the user.
	 * 
	 * @param result
	 *            result confirm credential.
	 */
	protected void finishConfirmCredentials(boolean result) {
		final Account account = new Account(mUsername, ProviderUtilities.ACCOUNT_TYPE);
		AccountManager.get(this).setPassword(account, password.getText().toString());
		final Intent intent = new Intent();
		intent.putExtra(AccountManager.KEY_BOOLEAN_RESULT, result);
		setAccountAuthenticatorResult(intent.getExtras());
		setResult(RESULT_OK, intent);
	}
	/**
	 * This method shows a custom dialog displaying the message given as a parameter.
	 * 
	 * @param message
	 *            message.
	 */
	public void showDialog(String message) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(message)
				.setCancelable(false)
				.setPositiveButton(getApplicationContext().getResources().getString(R.string.ok_button),
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {

								dialog.cancel();
							}
						});

		AlertDialog alertDialog = builder.create();
		alertDialog.setOwnerActivity(LoginActivity.this);
		alertDialog.show();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			finish();
			break;
		default:
			return super.onOptionsItemSelected(item);
		}

		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onPause()
	 */
	@Override
	protected void onPause() {
		super.onPause();

		if (progress != null && progress.isShowing()) {
			progress.cancel();
		}
	}

}
